package cn.net.shuxing.yifu.common.service;

import cn.net.shuxing.yifu.common.bean.*;
import cn.net.shuxing.yifu.common.constant.*;
import cn.net.shuxing.yifu.common.dto.BaseDto;
import cn.net.shuxing.yifu.common.mapper.UserWalletFrozeMapper;
import cn.net.shuxing.yifu.common.util.CommonExample;
import cn.net.shuxing.yifu.common.util.JedisUtil;
import cn.net.shuxing.yifu.common.util.RedisKeyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

@Service
public class UserWalletFrozeService extends BaseService<UserWalletFroze, UserWalletFrozeMapper> {

    @Autowired
    private MemberWalletService memberWalletService;

    @Autowired
    private UserCapitalUnfrozenHistoryService userCapitalUnfrozenHistoryService;

    @Autowired
    private OpenPriceHistoryService openPriceHistoryService;

    @Autowired
    private DealParamService dealParamService;

    @Autowired
    private AliveCoinActivateHistoryService aliveCoinActivateHistoryService;

    @Autowired
    private UserDealHistoryService userDealHistoryService;

    @Autowired
    private JedisUtil jedisUtil;

    @Autowired
    private UserService userService;

    @Autowired
    private UserCapitalService userCapitalService;

    @Autowired
    private UserRoleService userRoleService;

    public List<UserWalletFroze> getsByUserId(Integer userId) {
        CommonExample example = new CommonExample(UserWalletFroze.class);
        example.equals("userId", userId);
        return getsByExample(example);
    }

    public List<UserWalletFroze> getsByUserIdAndUserType(Integer userId, Integer userType) {
        CommonExample example = new CommonExample(UserWalletFroze.class);
        example.equals("userId", userId);
        example.equals("userType", userType);
        return getsByExample(example);
    }

    public List<UserWalletFroze> getsByUserIdAndUserTypeDESC(Integer userId, Integer userType) {
        CommonExample example = new CommonExample(UserWalletFroze.class);
        example.equals("userId", userId);
        example.equals("userType", userType);
        example.setOrderByClause("id DESC");
        return getsByExample(example);
    }

    public void exam(Integer userId, Integer coinTypeId, int userType) {
        LocalDateTime now = LocalDateTime.now();
        /** 考核周期，单位: 天 **/
//        User user = userService.getByPrimaryKeyWithoutComplete(userId);
        Integer examinationCycle = null;
        if (userType == UserType.MEMBER)
            examinationCycle = Integer.valueOf(dealParamService.getValue(userId, coinTypeId, UserParamConst.MEMBER_EXAMINATION_CYCLE));
        if (userType == UserType.SHAREHOLDER)
            examinationCycle = Integer.valueOf(dealParamService.getValue(userId, coinTypeId, UserParamConst.SHAREHOLDER_EXAMINATION_CYCLE));

        if (examinationCycle == null)
            return;
        //上次考核时间
        LocalDateTime lastDateTime = now.plusDays(0 - examinationCycle);

        AliveCoinActivateHistory aliveCoinActivateHistory = aliveCoinActivateHistoryService.getByMemberId(userId);
        LocalDateTime activateTime = aliveCoinActivateHistory.getUpdateTime();
        boolean flag = false;
        if (lastDateTime.compareTo(activateTime.plusDays(1)) < 0) {
            lastDateTime = activateTime;
            flag = true;
        }

        BigDecimal recieveCoinCount = new BigDecimal(0);
        BigDecimal sendCoinCount = new BigDecimal(0);

        if (flag) {
            recieveCoinCount = recieveCoinCount.add(aliveCoinActivateHistory.getCount());
        }

        List<UserDealHistory> userDealHistoryList = userDealHistoryService.getsByUserIdAndLastTime(userId, lastDateTime);
        for (UserDealHistory userDealHistory : userDealHistoryList) {
            if (userDealHistory.getDealType() == DealType.HANG_BUY || userDealHistory.getDealType() == DealType.TRANSFER_IN) {
                recieveCoinCount = recieveCoinCount.add(userDealHistory.getDealAliveCoinCount());
            } else {
                sendCoinCount = sendCoinCount.add(userDealHistory.getDealAliveCoinCount());
            }
        }

        UserCapital userCapital = userCapitalService.getByUserIdAndCoinTypeIdAndUserType(userId, coinTypeId, userType);
        recieveCoinCount = recieveCoinCount.add(userCapital.getSaveCount());
        BigDecimal movingPing = sendCoinCount.divide(recieveCoinCount, 8, BigDecimal.ROUND_HALF_UP);

        BigDecimal shouldMovingPing = null;
        if (userType == UserType.MEMBER)
            shouldMovingPing = new BigDecimal(dealParamService.getValue(userId, coinTypeId, UserParamConst.MEMBER_MOVING_PIN));
        if (userType == UserType.SHAREHOLDER)
            shouldMovingPing = new BigDecimal(dealParamService.getValue(userId, coinTypeId, UserParamConst.SHAREHOLDER_MOVING_PIN));

        if (shouldMovingPing == null) {
            userCapital.setSaveCount(userCapital.getAliveCoinCount());
            return;
        }

        if (movingPing.compareTo(shouldMovingPing) < 0) {
            frozeUser(userId, userType);
        }

        userCapital.setSaveCount(userCapital.getAliveCoinCount());

    }


    public void frozeUser(Integer userId, int userType) {
//        String uuid = UUID.randomUUID().toString();
        String orderNo = userDealHistoryService.createOrderNo(8);
        UserWalletFroze userWalletFroze = new UserWalletFroze();
        userWalletFroze.setUserId(userId);
        userWalletFroze.setUserType(userType);
        userWalletFroze.setOrderKey(orderNo);
        insert(userWalletFroze);
        userRoleService.updateState(userId, userType, UserState.FROZEN);
        User user = userService.getByPrimaryKeyWithoutComplete(userId);
        if (user.getType() == userType) {
            user.setState(UserState.FROZEN);
            userService.update(user);
        }
        int size = getsByUserIdAndUserType(userId, userType).size();
        Integer maxAllowThawCount = Integer.valueOf(dealParamService.getValue(userId, 1, UserParamConst.MEMBER_MAX_ALLOW_THAW_COUNT));
        if (size >= maxAllowThawCount) {
            userRoleService.updateState(userId, userType, UserState.DELETE);
        }
    }

    public BaseDto unFrozenUser(Integer userId, Integer userType) {
        List<UserCapital> userCapitals = userCapitalService.getsByUserId(userId);
        BaseDto baseDto = new BaseDto();
        List<UserWalletFroze> userWalletFrozes = getsByUserIdAndUserType(userId, userType);
        BigDecimal frozenMaxCount = new BigDecimal(0);
        if (userType == UserType.MEMBER) {
            frozenMaxCount = new BigDecimal(jedisUtil.get(RedisKeyCreator.memberFrozenMaxCount()));
        }
        if (userType == UserType.SHAREHOLDER) {
            frozenMaxCount = new BigDecimal(jedisUtil.get(RedisKeyCreator.shareholderFrozenMaxCount()));
        }
        if (new BigDecimal(userWalletFrozes.size()).compareTo(frozenMaxCount) == 0) {
            baseDto.setCode(CodeConst.ERROR);
            baseDto.setMsg("用户该身份解冻次数已达到上限");
        } else {
            if (userCapitals != null && !userCapitals.isEmpty()) {
                BigDecimal frozenBuyBackCount = new BigDecimal(0);
                BigDecimal frozenBuyBackFee = new BigDecimal(0);
                List<UserWalletFroze> userWalletFrozeList = new ArrayList<>();
                if (userType == UserType.MEMBER) {
                    frozenBuyBackFee = new BigDecimal(jedisUtil.get("m_frozenBuyBackFee"));
                    userWalletFrozeList = getsByUserIdAndUserType(userId, UserType.MEMBER);
                }
                if (userType == UserType.SHAREHOLDER) {
                    frozenBuyBackFee = new BigDecimal(jedisUtil.get("s_frozenBuyBackFee"));
                    userWalletFrozeList = getsByUserIdAndUserType(userId, UserType.SHAREHOLDER);
                }
                String orderKey = userWalletFrozeList.get(0).getOrderKey();
                for (UserCapital userCapital : userCapitals) {
                    if (userCapital.getState() != UserState.FROZEN) {
                        BaseDto.error("用户未被冻结");
                    } else {
                        BigDecimal openPrice = openPriceHistoryService.getOpenPrice(userCapital.getCoinTypeId());
                        BigDecimal aliveCoinCount = userCapital.getAliveCoinCount();
                        frozenBuyBackCount = openPrice.multiply(aliveCoinCount);
                        UserCapitalUnfrozenHistory unfrozenHistory = new UserCapitalUnfrozenHistory();
                        unfrozenHistory.setUserCapitalId(userCapital.getId());
                        unfrozenHistory.setCoinTypeId(userCapital.getCoinTypeId());
                        unfrozenHistory.setUserId(userId);
                        unfrozenHistory.setUserType(userType);
                        unfrozenHistory.setCount(userCapital.getAliveCoinCount());
                        userCapitalUnfrozenHistoryService.insert(unfrozenHistory);
                        userCapital.setAliveCoinCount(new BigDecimal(0));
                        userCapitalService.update(userCapital);
                        BigDecimal fee = frozenBuyBackCount.multiply(frozenBuyBackFee);
                        BigDecimal dealCount = frozenBuyBackCount.subtract(fee);
                        memberWalletService.addCash(userId, dealCount, CashChangeType.CASH_UNFROZEN_BUY_BACK, orderKey);
                    }
                }
//                userDealHistoryService.insert(userId, 0, DealType.FEE, DealScene.FROZEN_BUY_BACK, fee, new BigDecimal(0), userType, userWalletFrozeList.get(0).getOrder_key());
                baseDto.setData("解冻成功");
            }
        }
        baseDto.setData("解冻失败");
        return baseDto;
    }
}
